package com.aote.expression;

import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.aote.expression.occasion.OccasionCondition;
import com.browsesoft.PropertiesService;
import com.browsesoft.htmlcomponent.HTMLBasicComponent;

/**
 * 时机条件处理工厂
 * 
 */
public class OccasionConditionFactory {

	/**
	 * 单例
	 */
	private static OccasionConditionFactory self = new OccasionConditionFactory();

	/**
	 * 保存时机条件的map
	 * 
	 */
	private static Map occasions = new HashMap();

	/**
	 * 默认时机条件标识
	 */
	private static String defaultOccasion = "";

	private OccasionConditionFactory() {

	}

	public static OccasionConditionFactory getInstance() {
		if (occasions.size() == 0) {
			load();
		}
		return self;
	}

	/**
	 * 判断是否合适
	 * 
	 * @param occasionName
	 *            时机条件标识名
	 * @param attrs
	 *            属性集合
	 * @param name
	 *            输入筐名称
	 * @return
	 */
	public boolean isFit(String occasionName, Map attrs, String name,
			Element elem, HTMLBasicComponent component) {
		OccasionCondition oc = this.getOccasionCondition(occasionName);
		return oc.isFit(attrs, name, elem, component);
	}

	/**
	 * 根据时机标识得到时机条件类，如果标识为空，返回默认的时机条件
	 */
	public OccasionCondition getOccasionCondition(String name) {
		if (name == null || name.equals("")) {
			return (OccasionCondition) occasions.get(defaultOccasion);
		} else {
			return (OccasionCondition) occasions.get(name);
		}
	}

	/**
	 * 装载
	 */
	private static void load() {
		Element elem = (Element) PropertiesService.getDocument()
				.getElementsByTagName("occassions").item(0);
		// 得到默认时机条件标识
		defaultOccasion = elem.getAttribute("default");
		// 创建时机条件类
		NodeList list = elem.getChildNodes();
		for (int i = 0; i < list.getLength(); i++) {
			if (list.item(i).getNodeType() == Node.ELEMENT_NODE) {
				Element child = (Element) list.item(i);
				String tag = child.getTagName();
				String className = child.getAttribute("className");
				OccasionCondition oc = createOccasionCondition(className);
				occasions.put(tag, oc);
			}
		}
	}

	/**
	 * 创建时机条件
	 */
	private static OccasionCondition createOccasionCondition(String className) {
		try {
			OccasionCondition result = (OccasionCondition) Class.forName(
					className).newInstance();
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
